/**
 *
 */
package com.ybkj.daijia.api.driver.v2;

import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.api.driver.Error;
import com.ybkj.daijia.api.driver.ErrorConstant;
import com.ybkj.daijia.api.driver.SecurityUtils;
import com.ybkj.daijia.api.driver.transport.ResultTransport;
import com.ybkj.daijia.common.IdcardUtils;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.server.event.model.ActivityCheckEvent;
import com.ybkj.daijia.server.event.model.OrderFillV2Event;
import com.ybkj.daijia.server.event.model.OrderRecordEvent;
import com.ybkj.daijia.server.mc.Passenger;
import com.ybkj.daijia.server.model.Area;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.Driver;
import com.ybkj.daijia.server.model.DriverApply;
import com.ybkj.daijia.server.model.Order;
import com.ybkj.daijia.server.model.Order.OrderCarType;
import com.ybkj.daijia.server.model.Order.OrderCarTypeDetail;
import com.ybkj.daijia.server.reactor.ReactorVo;
import com.ybkj.daijia.server.sales.Activity.ActivityEvent;
import com.ybkj.daijia.server.service.AreaService;
import com.ybkj.daijia.server.service.CompanyService;
import com.ybkj.daijia.server.service.DriverApplyService;
import com.ybkj.daijia.server.service.DriverService;
import com.ybkj.daijia.server.service.FinancialRecordService;
import com.ybkj.daijia.server.service.MemberAccountService;
import com.ybkj.daijia.server.service.MemberService;
import com.ybkj.daijia.server.service.OrderService;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.WebUtils;

/**
 * @author bo
 *
 */
@Controller("driverProcessV2Controller")
@RequestMapping(value = "driver/api/rest/v2")
public class ProcessController {

    private static final Logger logger = LoggerFactory.getLogger(ProcessController.class);

    @Autowired
    private DriverService driverService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private CompanyService companyService;

    @Autowired
    private AreaService areaService;

    @Autowired
    private MemberAccountService memberAccountService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private FinancialRecordService financialRecordService;

    @Autowired
    private DriverApplyService driverApplyService;

    @Autowired
    private SettingUtils settingUtils;

    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;

    /**
     * 补单
     * @param driverID
     * @param xml
     * @param appKey
     * @param token
     * @param timestamp
     * @return
     */
    @RequestMapping(value = "fillOrder", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport fillOrder(
        Long driverID,
        String fromPlace, Double clientLongitude, Double clientLatitude,
        String clientName, String clientPhone, Long serverTimeStamp,
        String appKey, String token, String timestamp) {

        logger.debug(
            "recv driverID:{},fromPlace:{},clientLongitude:{},clientLatitude:{},clientName:{},clientPhone:{},serverTimeStamp:{},appKey:{},token:{},timestamp:{}",
            driverID, fromPlace, clientLongitude, clientLatitude, clientName, clientPhone,
            serverTimeStamp, appKey, token, timestamp);

        if (null == driverID || null == fromPlace || null == clientLongitude
            || null == clientLatitude ||
            StringUtils.isBlank(clientPhone) || null == serverTimeStamp ||
            SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        if (!StringUtils.isNumeric(timestamp) || !SecurityUtils
            .checkTimestamp(Long.parseLong(timestamp))) {
            return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(driverID));
        params.add(String.valueOf(fromPlace));
        params.add(String.valueOf(clientLongitude));
        params.add(String.valueOf(clientLatitude));
        params.add(String.valueOf(clientName));
        params.add(String.valueOf(clientPhone));
        params.add(String.valueOf(serverTimeStamp));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        try {

            Driver driver = driverService.findOne(driverID);

            if (null == driver) {
                return ResultTransport.getErrorBy(ErrorConstant.DRIVER_NOT_EXISTS);
            }
            if (driver.getIsFreeze()) {
                return ResultTransport.getErrorBy(ErrorConstant.USER_IS_FREEZE_ERROR);
            }
            if (driver.getStatus().equals(Driver.DRIVER_OFFLINE)) {
                return ResultTransport.getErrorBy(new Error(-27, "未上线，不能补单"));
            } else if (!driver.getStatus().equals(Driver.DRIVER_ONLINE)) {
                return ResultTransport.getErrorBy(new Error(-27, "忙碌中，不能补单"));
            }

            if (!driver.getDriverJobType().equals(Driver.DriverJobType.all)) {
                if (!driver.getDriverJobType().contains(Driver.DriverJobType.daijia.toString())) {
                    return ResultTransport.getErrorBy(ErrorConstant.ORDER_IS_DAIJIA_ERROR);
                }
            }

            Order order = new Order();

            order.setFromPlace(fromPlace);
            order.setClientLongitude(clientLongitude);
            order.setClientLatitude(clientLatitude);
            order.setClientName(clientName);
            order.setClientPhone(clientPhone.replaceAll(" ", ""));
            order.setServerTime(new Date(serverTimeStamp));
            order.setStatus(Order.ORDER_STATUS_NEW);
            order.setOrderCarType(OrderCarType.daijia);
            order.setOrderCarTypeDetail(OrderCarTypeDetail.jhdj);

            Passenger passenger = memberService.findOnePassengerByPhone(order.getClientPhone());

            Result<Order> result = orderService.fillOrderV2(order, driverID);

            if (!result.isSuccess()) {
                return ResultTransport.getErrorBy(new Error(-4, result.getMessage()));
            }

            if (null == passenger) {
                passenger = memberService.findOnePassengerByPhone(order.getClientPhone());
                ReactorVo rVo = new ReactorVo();
                rVo.setPassenger(passenger);
                rVo.setActivityEvent(ActivityEvent.newRegister);
                ActivityCheckEvent activityCheckEvent = new ActivityCheckEvent(rVo);
                applicationEventMulticaster.multicastEvent(activityCheckEvent);
            }

            //补单v2事件
            OrderFillV2Event fillV2Event = new OrderFillV2Event(order);
            applicationEventMulticaster.multicastEvent(fillV2Event);

            OrderRecordEvent orderRecordEvent = new OrderRecordEvent(order);
            applicationEventMulticaster.multicastEvent(orderRecordEvent);

            Company thisCompany = companyService.findOne(order.getCompanyId());
            if (null != thisCompany) {
                if (null != passenger) {
                    Area daijiaArea = null;
                    if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
                        daijiaArea = areaService.findDaijiaByPassenger(passenger.getId());
                    } else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
                        daijiaArea = areaService
                            .findDaijiaByEnterprise(passenger.getEnterprise_id());
                    }

                    if (null != daijiaArea) {
                        thisCompany.setArea(areaService.findOneWithCharge(daijiaArea.getId()));
                    } else {
                        thisCompany.setArea(areaService.findOneWithCharge(thisCompany.getAreaId()));
                    }
                } else {
                    thisCompany.setArea(areaService.findOneWithCharge(thisCompany.getAreaId()));
                }
            }
            order.setCompany(thisCompany);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS); //补单成功
            instance.setData(order);

            return instance;

        } catch (Exception e) {
            logger.error("api v2 driver fillOrder error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }


    /**
     * 申请司机
     * @param appKey
     * @param token
     * @param timestamp
     * @return
     */
    @RequestMapping(value = "driverApply", method = RequestMethod.POST)
    public synchronized @ResponseBody
    ResultTransport driverApply(
        String realname, String idCard, String phone,
        HttpServletRequest req,
        @RequestParam(required = false, value = "photo") MultipartFile photoFile,
        @RequestParam(required = false, value = "idCardPhoto") MultipartFile idCardPhotoFile,
        @RequestParam(required = false, value = "license") MultipartFile licenseFile,
        String introducer,
        String appKey, String token, String timestamp) {

        logger.debug(
            "recv realname:{},idCard:{},phone:{},introducer{},appKey:{},token:{},timestamp:{}",
            realname, idCard, phone, introducer, appKey, token, timestamp);

        if (StringUtils.isBlank(realname) || StringUtils.isBlank(idCard) || StringUtils
            .isBlank(phone)
            || null == photoFile || null == idCardPhotoFile || null == licenseFile
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        if (!StringUtils.isNumeric(timestamp) || !SecurityUtils
            .checkTimestamp(Long.parseLong(timestamp))) {
            return ResultTransport.getErrorBy(ErrorConstant.TIMESTAMP_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(realname));
        params.add(String.valueOf(idCard));
        params.add(String.valueOf(phone));
        params.add(String.valueOf(introducer));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        if (null != driverService.findByIdCard(idCard)) {
            return ResultTransport.getErrorBy(ErrorConstant.IDCARD_HAS_EXISTS);
        }

        if (null != driverService.findByPhone(phone)) {
            return ResultTransport.getErrorBy(ErrorConstant.PHONE_HAS_EXISTS);
        }

        if (null != driverApplyService.findByIdCard(idCard)) {
            return ResultTransport.getErrorBy(ErrorConstant.DRIVERAPPLY_HAS_EXISTS);
        }

        if (null != driverApplyService.findByPhone(phone)) {
            return ResultTransport.getErrorBy(ErrorConstant.DRIVERAPPLY_HAS_EXISTS);
        }

        try {

            DriverApply driverApply = new DriverApply();
//            driverApply.setGender(IdcardUtils.getGenderByIdCard(idCard));
            driverApply.setIdCard(StringUtils.trimToEmpty(idCard).toLowerCase());
            driverApply.setPhone(StringUtils.trimToEmpty(phone));
            driverApply.setRealname(realname);
            driverApply.setIntroducer(introducer);

            if (null != photoFile) {
                try {
                    String bathPath = getBasePath(req);

                    File dir = new File(bathPath, "upload/driver");

                    FileUtils.forceMkdir(dir);

                    SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");

                    String fileName = String
                        .format("%s.png", df.format(new Date()) + "_" + new Random().nextInt(1000));

                    byte[] data = photoFile.getBytes();
                    FileOutputStream out = new FileOutputStream(new File(dir, fileName));
                    IOUtils.write(data, out);
                    IOUtils.closeQuietly(out);

                    driverApply.setPhoto(fileName);
                } catch (Exception e) {
                    logger.debug(e.getMessage());
                }
            }

            if (null != idCardPhotoFile) {
                try {
                    String bathPath = getBasePath(req);

                    File dir = new File(bathPath, "upload/idCardPhoto");

                    FileUtils.forceMkdir(dir);

                    SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");

                    String fileName = String
                        .format("%s.png", df.format(new Date()) + "_" + new Random().nextInt(1000));

                    byte[] data = idCardPhotoFile.getBytes();
                    FileOutputStream out = new FileOutputStream(new File(dir, fileName));
                    IOUtils.write(data, out);
                    IOUtils.closeQuietly(out);

                    driverApply.setIdCardPhoto(fileName);
                } catch (Exception e) {
                    logger.debug(e.getMessage());
                }
            }

            if (null != licenseFile) {
                try {
                    String bathPath = getBasePath(req);

                    File dir = new File(bathPath, "upload/license");

                    FileUtils.forceMkdir(dir);

                    SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");

                    String fileName = String
                        .format("%s.png", df.format(new Date()) + "_" + new Random().nextInt(1000));

                    byte[] data = licenseFile.getBytes();
                    FileOutputStream out = new FileOutputStream(new File(dir, fileName));
                    IOUtils.write(data, out);
                    IOUtils.closeQuietly(out);

                    driverApply.setLicensePhoto(fileName);
                } catch (Exception e) {
                    logger.debug(e.getMessage());
                }
            }

            driverApplyService.insertRecord(driverApply);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);

            return instance;

        } catch (Exception e) {
            logger.error("api v2 driver driverApply error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }

    }

    private String getBasePath(HttpServletRequest req) {

        try {
            return WebUtils.getRealPath(req.getSession().getServletContext(), "/");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        return StringUtils.EMPTY;
    }

}